package com.wjf.birdfish.commons;

import java.io.Serializable;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;

import com.wjf.birdfish.hibernate.Page;
import com.wjf.birdfish.hibernate.PageBuilder;
import com.wjf.birdfish.util.GenericsUtils;
import com.wjf.birdfish.util.PageSearchEntity;


/**
 * Created on 2006-10-28
 * <p>Title: 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类.</p>
 * <p>Description:子类只要在类定义时指定所管理Entity的Class, 即拥有对单个Entity对象的CRUD操作.
 * eg.
 * <pre>
 * public class ArticleDao extends HibernateEntityDao<User>{
 * }
 * </pre>
 * </p> 
 * <p>Copyright: Copyright TYDIC (c) 2006</p>
 * <p>Company: tydic.com</p>
 * @author <a href="mailto:tongys@tydic.com">童永胜</a>
 * @see HibernateGenericDao
 * @version 1.0
 */
@SuppressWarnings("unchecked")
abstract public class HibernateAbstractDao<T> extends HibernateGenericDao {
	protected Logger log = Logger.getLogger(getClass().getName());
	/**
     * DAO所管理的Entity类型.
     */
    protected Class<T> entityClass;

    /**
     * 取得entityClass.
     * JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
     */
    protected Class<T> getEntityClass() {
        return entityClass;
    }

    /**
     * 在构造函数中将泛型T.class赋给entityClass
     */
    public HibernateAbstractDao() {
        entityClass = GenericsUtils.getGenericClass(getClass());
    }

    /**
     * 根据ID获取对象
     */
    public T get(Serializable id) {
        return get(getEntityClass(), id);
    }

    /**
     * 获取全部对象
     */
    public List<T> getAll() {
        return getAll(getEntityClass(), false);
    }
    
    /**
     * 获取全部对象，包括或不包括状态为无效的对象
     * @param useState true=有效，false=无效
     * @return
     */
    public List<T> getAll(boolean useState) {
        return getAll(getEntityClass(), useState);
    }
    
    /**
     * 获取所属单位的全部对象
     * @param orgId 单位编号
     * @return
     */
    public List<T> getAll(String orgId) {
        return getAll(getEntityClass(), orgId, false);
    }
    
    public List<T> getAll(String orgId, boolean useState) {
        return getAll(getEntityClass(), orgId, useState);
    }
    
    /**
     * 根据属性名和属性值查询对象.
     *
     * @return 符合条件的对象列表
     */
    public List<T> findBy(String name, Object value) {
        return findBy(getEntityClass(), name, value);
    }
    
    /**
     * 根据属性名和属性值查询所属的单位编号(orgId)的对象.
     * @param name
     * @param value
     * @param orgId 单位编号
     * @return
     */
    public List<T> findBy(String name, Object value, String orgId) {
        return findBy(getEntityClass(), name, value, orgId);
    }

    /**
     * 根据属性名和属性值查询单个对象.
     *
     * @return 符合条件的唯一对象
     */
    public T findUniqueBy(String name, Object value) {
        return findUniqueBy(getEntityClass(), name, value);
    }
    
    /**
     * 根据属性名和属性值查询所属某个单位(orgId)的单个对象.
     * @param name
     * @param value
     * @param orgId 单位编号
     * @return 符合条件的唯一对象
     */
    public T findUniqueBy(String name, Object value, String orgId) {
        return findUniqueBy(getEntityClass(), name, value, orgId);
    }
    
    /**
     * 根据属性名和属性值查询单个对象.
     *
     * @return 符合条件的唯一对象
     */
    public T findUniqueBy2(String name, Object value) {
        return findUniqueBy2(getEntityClass(), name, value);
    }

    /**
     * 根据属性名和属性值以Like AnyWhere方式查询对象.
     */
    public List<T> findByLike(String name, String value) {
        return findByLike(getEntityClass(), name, value);
    }

    /**
     * 取得Entity的Criteria.
     */
    protected Criteria getEntityCriteria() {
        return getEntityCriteria(getEntityClass());
    }

    /**
     * 判断对象某些属性的值在数据库中不存在重复
     *
     * @param names 在POJO里不能重复的属性列表,以逗号分割
     *              如"name,loginid,password"
     */
    public boolean isNotUnique(Object entity, String names) {
        return isNotUnique(getEntityClass(), entity, names);
    }
    
    public com.wjf.birdfish.util.Page findByEntity(PageSearchEntity pEntity, int pageNo, int pageSize, String orgId) {                    
    	pEntity.addSearch("orgId", orgId, "=");
    	return findByEntity(getEntityClass(), pEntity, pageNo, pageSize);
    }
    
    public com.wjf.birdfish.util.Page findByEntity(PageSearchEntity pEntity, int pageNo, int pageSize) {
    	return findByEntity(getEntityClass(), pEntity, pageNo, pageSize);
    }
    public com.wjf.birdfish.util.Page findByEntity2(PageSearchEntity pEntity, int pageNo, int pageSize) {
    	return findByEntity2(getEntityClass(), pEntity, pageNo, pageSize);
    }
    
    
    /**
     * @author tongys
     * 根据参数得到List
     * @throws Exception
     */
    public List<T> findListByEntity(PageSearchEntity entity) {
    	return findListByEntity(getEntityClass(),entity);
    }
    
    public int getInitOrder(String orderName) {
    	return this.getInitOrder(getEntityClass(), orderName);
    }
    
    public int getInitOrder2(String orderName) {
    	return this.getInitOrder2(getEntityClass(), orderName);
    }
    public Page<T> getAsPage(int pageIndex, int pageSize) {
    	Page<T> page = new PageBuilder<T>(getEntityClass(), getSession())
				.pageSize(pageSize).create();
		page.gotoPage(pageIndex);
		return page;
	}
	
	public Page<T> getAsPage(int pageIndex, int pageSize, String hql, String ... params) {
		if (params != null) {
			if (params.length == 0) {
				params = null;
			}
		}
		Page<T> page;
		if (params == null) {
			page = new PageBuilder<T>(getSession(), hql).pageSize(pageSize).create();
		} else {
			page = new PageBuilder<T>(getSession(), hql, (Object) params).pageSize(pageSize).create();
		}
		page.gotoPage(pageIndex);
		return page;
	}
}
